package org.hbhk.hxl.gateway.redis;

import java.text.NumberFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
import com.google.common.cache.LoadingCache;

public class GuavaCacheManager {

	protected  final static Logger logger = LoggerFactory.getLogger(GuavaCacheManager.class);

	// size)来更改
	private static int expireAfterWriteDuration = 10; // 数据存在时长，子类在构造方法中调用setExpireAfterWriteDuration(int
	// duration)来更改
	private static  TimeUnit timeUnit = TimeUnit.MINUTES; // 时间单位（分钟）

	private static LoadingCache<String, Object> cache;

	
	private static GuavaCacheManager guavaCacheManager;
	
	private GuavaCacheManager() {
	}
	/**
	 * 通过调用getCache().get(key)来获取数据
	 * 
	 * @return cache
	 */
	private static LoadingCache<String, Object> getCache() {
		if (cache == null) { // 使用双重校验锁保证只有一个cache实例
			synchronized (logger) {
				if (cache == null) {
					guavaCacheManager = new GuavaCacheManager();
					cache = CacheBuilder.newBuilder()
							// 缓存数据的最大条目，也可以使用.maximumWeight(weight)代替
							.expireAfterWrite(expireAfterWriteDuration,
									timeUnit) // 数据被创建多久后被移除
							.recordStats() // 启用统计
							.build(new CacheLoader<String, Object>() {
								@Override
								public Object load(String key) throws Exception {
									return null;
								}
							});
				}
			}
		}

		return cache;
	}
	
	public static GuavaCacheManager   getInstance(){
		getCache();
		return guavaCacheManager;
	}

	/**
	 * 根据key从数据库或其他数据源中获取一个value，并被自动保存到缓存中。
	 * 
	 * @param key
	 * @return value,连同key一起被加载到缓存中的。
	 */
	public void put(String key, Object value) {
		cache.put(key, value);
	}

	@SuppressWarnings("unchecked")
	public <T> T  get(String key){
		try {
			Object result = cache.get(key);
			return (T) result;
		} catch (Exception e) {
			return null;
		}
	}

	public void remove(String key) {
		try {
			cache.invalidate(key);
		} catch (Exception e) {
		}
	}


	public int getExpireAfterWriteDuration() {
		return expireAfterWriteDuration;
	}


	/**
	 * 返回一个缓存的统计数据
	 * 
	 * @param cacheName
	 * @return Map<统计指标，统计数据>
	 */
	public static Map<String, Object> getCacheStatsToMap() {
		Map<String, Object> map = new LinkedHashMap<>();
		CacheStats cs = cache.stats();
		NumberFormat percent = NumberFormat.getPercentInstance(); // 建立百分比格式化用
		percent.setMaximumFractionDigits(1); // 百分比小数点后的位数
		map.put("cacheName", "localCache");
		map.put("size", cache.size());
		map.put("survivalDuration", expireAfterWriteDuration);
		map.put("hitCount", cs.hitCount());
		map.put("hitRate", percent.format(cs.hitRate()));
		map.put("missRate", percent.format(cs.missRate()));
		map.put("loadSuccessCount", cs.loadSuccessCount());
		map.put("loadExceptionCount", cs.loadExceptionCount());
		map.put("totalLoadTime", cs.totalLoadTime() / 1000000); // ms
		return map;
	}

}